package edu.ksu.cis.indus.toolkits.bandera;

import edu.ksu.cis.bandera.tool.Tool;
import edu.ksu.cis.bandera.tool.ToolConfigurationView;
import edu.ksu.cis.bandera.tool.ToolIconView;
import edu.ksu.cis.bandera.util.BaseObservable;
import edu.ksu.cis.indus.common.soot.CompleteStmtGraphFactory;
import edu.ksu.cis.indus.processing.Environment;
import edu.ksu.cis.indus.slicer.SliceCriteriaFactory;
import edu.ksu.cis.indus.slicer.transformations.TagBasedDestructiveSliceResidualizer;
import edu.ksu.cis.indus.staticanalyses.tokens.BitSetTokenManager;
import edu.ksu.cis.indus.staticanalyses.tokens.soot.SootValueTypeManager;
import edu.ksu.cis.indus.tools.Phase;
import edu.ksu.cis.indus.tools.slicer.SlicerToolHelper;
import edu.ksu.cis.indus.tools.slicer.criteria.specification.SliceCriteriaParser;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.jibx.runtime.BindingDirectory;
import org.jibx.runtime.IBindingFactory;
import org.jibx.runtime.IMarshallingContext;
import org.jibx.runtime.IUnmarshallingContext;
import org.jibx.runtime.JiBXException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import soot.Scene;
import soot.SootMethod;

public final class SlicerTool2 extends BaseObservable
  implements Tool
{
	
	edu.ksu.cis.indus.toolkits.bandera.SlicerTool a;
  public static final Object CRITERIA = "slicingCriteria";

  public static final Object CRITERIA_SPECIFICATION = "slicingCriteriaSpecification";

  public static final Object ID_OF_CONFIGURATION_TO_USE = "idOfConfigurationToUse";

  public static final Object ROOT_METHODS = "entryPoints";

  public static final Object SCENE = "scene";
  private static final List<Object> IN_ARGUMENTS_IDS;
  private static final Logger LOGGER = LoggerFactory.getLogger(SlicerTool.class);
  private static final List<Object> OUT_ARGUMENTS_IDS;
  private static final String TAG_NAME = "Slicer:Bandera";
  private boolean abortFlag;
  private SlicerConfiguration configuration;
  private SlicerConfigurationView configurationView;
  private boolean configurationWasProvided;
  private Scene scene;
  private final edu.ksu.cis.indus.tools.slicer.SlicerTool tool;

  static
  {
    IN_ARGUMENTS_IDS = new ArrayList();
    IN_ARGUMENTS_IDS.add(SCENE);
    IN_ARGUMENTS_IDS.add(ROOT_METHODS);
    IN_ARGUMENTS_IDS.add(CRITERIA);
    IN_ARGUMENTS_IDS.add(CRITERIA_SPECIFICATION);
    OUT_ARGUMENTS_IDS = new ArrayList();
    OUT_ARGUMENTS_IDS.add(SCENE);
  }

  public SlicerTool2()
  {
    this.tool = 
      new edu.ksu.cis.indus.tools.slicer.SlicerTool(new BitSetTokenManager(new SootValueTypeManager()), 
      new CompleteStmtGraphFactory());
    this.tool.setTagName("Slicer:Bandera");
    this.configurationView = new SlicerConfigurationView(this.tool.getConfigurator());
  }

  public String getConfiguration()
  {
    try
    {
      this.configuration.slicerConfigurationStr = this.tool.stringizeConfiguration();

      IBindingFactory _bfact = BindingDirectory.getFactory(SlicerConfiguration.class);
      IMarshallingContext _mctx = _bfact.createMarshallingContext();
      _mctx.setIndent(4);

      ByteArrayOutputStream _b = new ByteArrayOutputStream();
      _mctx.marshalDocument(this.configuration, "UTF-8", null, _b);
      return _b.toString();
    } catch (JiBXException _e) {
      UnknownError _r = new UnknownError();
      _r.initCause(_e);
      throw _r;
    }
  }

  public List getInputParameterList()
  {
    return Collections.unmodifiableList(IN_ARGUMENTS_IDS);
  }

  public Map getOutputMap()
  {
    Map _outputMap = new HashMap();
    _outputMap.put(SCENE, this.scene);
    return _outputMap;
  }

  public List getOutputParameterList()
  {
    return Collections.unmodifiableList(OUT_ARGUMENTS_IDS);
  }

  public ToolConfigurationView getToolConfigurationView()
  {
    return this.configurationView;
  }

  public ToolIconView getToolIconView()
  {
    return this.configurationView;
  }

  public void quit()
    throws Exception
  {
    this.tool.abort();
    this.abortFlag = true;
  }

  public void run()
    throws Exception
  {
    if (LOGGER.isInfoEnabled()) {
      LOGGER.info("BEGIN: bandera slicer tool");
    }
    this.abortFlag = false;

    if (!(this.configurationWasProvided)) {
      String _msg = "No configuration was provided.  Aborting!!!";
      LOGGER.error("No configuration was provided.  Aborting!!!");
      throw new IllegalArgumentException("No configuration was provided.  Aborting!!!");
    }

    this.tool.run(Phase.STARTING_PHASE, null, true);

    SlicerToolHelper.optimizeForSpaceBeforeResidualization(this.tool, this.configuration.retentionList);

    if (!(this.abortFlag)) {
      TagBasedDestructiveSliceResidualizer _residualizer = new TagBasedDestructiveSliceResidualizer();
      _residualizer.setTagToResidualize("Slicer:Bandera");
      _residualizer.setBasicBlockGraphMgr(this.tool.getBasicBlockGraphManager());
      _residualizer.residualizeSystem(this.tool.getSystem());
    }

    if (this.configuration.eraseUnnecessaryClasses) {
      SlicerToolHelper.optimizeForSpaceAfterResidualization(this.tool, this.configuration.retentionList);
    }

    if (LOGGER.isInfoEnabled())
      LOGGER.info("END: bandera slicer tool");
  }

  public void setConfiguration(String configStr)
    throws Exception
  {
    this.configurationWasProvided = ((configStr != null) && (configStr.length() > 0));

    IBindingFactory _bfact = BindingDirectory.getFactory(SlicerConfiguration.class);
    IUnmarshallingContext _uctx = _bfact.createUnmarshallingContext();
    this.configuration = 
      ((SlicerConfiguration)_uctx.unmarshalDocument(
      new BufferedInputStream(new ByteArrayInputStream(configStr.getBytes())), null));
    this.tool.destringizeConfiguration(this.configuration.slicerConfigurationStr);
  }

  public void setInputMap(Map inputArgs)
  {
    this.scene = ((Scene)inputArgs.get(SCENE));

    if (this.scene == null) {
      String _msg = "A scene must be provided for slicing.";
      LOGGER.error("A scene must be provided for slicing.");
      throw new IllegalArgumentException("A scene must be provided for slicing.");
    }
    this.tool.setSystem(new Environment(this.scene));

    this.tool.clearCriteria();

    Collection _criteria = (Collection)(Collection)inputArgs.get(CRITERIA);

    if ((_criteria == null) || (_criteria.isEmpty())) {
      LOGGER.warn("Deadlock criteria will be used.");
    } else {
      this.tool.addCriteria(_criteria);

      for (Iterator _i = _criteria.iterator(); _i.hasNext(); ) {
        Object _o = _i.next();

        if (!(SliceCriteriaFactory.isSlicingCriterion(_o))) {
          LOGGER.error(_o + " is an invalid slicing criterion.  " + 
            "All slicing criterion should be created via SliceCriteriaFactory.");
          throw new IllegalArgumentException("Slicing criteion " + _o + 
            " was not created via SliceCriteriaFactory.");
        }
      }
    }

    String _criteriaSpec = (String)inputArgs.get(CRITERIA_SPECIFICATION);

    if (_criteriaSpec == null)
      LOGGER.info("No criteria specification provided.");
    else {
      try {
        this.tool.addCriteria(SliceCriteriaParser.deserialize(_criteriaSpec, this.scene));
      } catch (JiBXException _e) {
        String _msg = "Error occurred while deserializing the provided criteria specification.";
        LOGGER.error("Error occurred while deserializing the provided criteria specification.");

        IllegalArgumentException _t = new IllegalArgumentException("Error occurred while deserializing the provided criteria specification.");
        _t.initCause(_e);
        throw _t;
      }
    }

    Collection _rootMethods = (Collection)(Collection)inputArgs.get(ROOT_METHODS);

    if ((_rootMethods == null) || (_rootMethods.isEmpty())) {
      String _msg = "Atleast one method should be specified as the entry-point into the system.";
      LOGGER.error("Atleast one method should be specified as the entry-point into the system.");
      throw new IllegalArgumentException("Atleast one method should be specified as the entry-point into the system.");
    }
    this.tool.setRootMethods(_rootMethods);

    String _activeConfID = (String)inputArgs.get(ID_OF_CONFIGURATION_TO_USE);

    if (_activeConfID == null)
      LOGGER.info("No active configuration was specified.  Using the default in the provided configuration.");
    else {
      this.tool.setActiveConfiguration(_activeConfID);
    }
      
  }
}

/* Location:           D:\tool\banderaCLI-1.0a4\lib\indus\slicer.jar
 * Qualified Name:     edu.ksu.cis.indus.toolkits.bandera.SlicerTool
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.5.3
 */